package com.xxd;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.security.Key;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/**
 * @description:
 * @author: xuxd
 * @time: 2019/12/2 11:00
 */
public class EncryUtil {
	private static final String BASE_KEY = "copy1`34";
	private static final String ALGORITHM = "DES";
	private final static String CHARSET = "utf-8";
	private static final String CIPHER_ALGORITHM = "DES/ECB/PKCS5Padding";
	public static final BASE64Decoder base64Decoder = new BASE64Decoder();
	public static final BASE64Encoder base64Encoder = new BASE64Encoder();

	private static Key getSecretKeySpec() throws Exception {
		return new SecretKeySpec(BASE_KEY.getBytes(CHARSET), ALGORITHM);
	}

	private static Cipher getCipher(int mode) throws Exception {
		Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
		cipher.init(mode, getSecretKeySpec());
		return cipher;
	}

	private static String encrypt(String source) throws Exception {
		Cipher cipher = getCipher(Cipher.ENCRYPT_MODE);
		return base64Encoder.encode(cipher.doFinal(source.getBytes(CHARSET)));
	}

	private static String decrypt(String source) throws Exception {
		Cipher cipher = getCipher(Cipher.DECRYPT_MODE);
		return new String(cipher.doFinal(base64Decoder.decodeBuffer(source)), CHARSET);
	}

	public static String readCrypt(File file) {
		try {
			FileInputStream in = new FileInputStream(file);
			byte[] filecontent = new byte[in.available()];
			in.read(filecontent);
			in.close();
			return new String(filecontent, CHARSET);
		} catch (Exception e) {
			new RuntimeException("Read Licence File Error!");
		}
		return null;
	}

	public static String readCrypt(String fileName) {
		try {
			File file = new File(fileName);
			FileInputStream in = new FileInputStream(file);
			byte[] filecontent = new byte[in.available()];
			in.read(filecontent);
			in.close();
			return new String(filecontent, CHARSET);
		} catch (Exception e) {
			new RuntimeException("Read Licence File Error!");
		}
		return null;
	}

	public static boolean verify(String str) {
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
		boolean flag = false;
		try {
			Map<String, String> source = splitCrypt(str);
			String expired = source.get(SystemInfo.EXPIRED);
			Date expiredDate = simpleDateFormat.parse(expired);
			String dataVersion = source.get(SystemInfo.DATA_VERSION);
			if (!dataVersion.equals(SystemInfo.getSysInfoMap().get(SystemInfo.DATA_VERSION))) {
				throw new RuntimeException("System version is not Matched!");
			} else if (expiredDate.getTime() < System.currentTimeMillis()) {
				throw new RuntimeException("Licence is expired! The date is :" + expired);
			} else {
				if (source.keySet().contains("127.0.0.1") || source.keySet().contains("localhost")) {
					flag = true;
					return flag;
				}
				for (Object key : source.keySet()) {
					System.out.println(source.get(key).toUpperCase());
					if (!SystemInfo.DATA_VERSION.equals(key) && !SystemInfo.EXPIRED.equals(key)
							&& source.get(key).toUpperCase().equals(SystemInfo.getSysInfoMap().get(key))) {
						flag = true;
						break;
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return flag;
	}

	private static Map<String, String> splitCrypt(String str) throws Exception {
		String newA = EncryUtil.decrypt(str);
		System.out.println("==============" + newA + "==============");
		String[] array = newA.split(",");
		Map<String, String> map = new HashMap<String, String>();
		if (array.length >= 1) {
			for (String item : array) {
				if (item != null) {
					String[] mp = item.split(":");
					map.put(String.valueOf(mp[0]), String.valueOf(mp[1]));
				}
			}
		}
		return map;
	}

	public static void main(String arg[]) throws Exception {
		Scanner scan = new Scanner(System.in);
		System.out.println("设置dataVersion.code:");
		String dataVersion = scan.nextLine();
		SystemInfo.updateInfo(SystemInfo.DATA_VERSION, dataVersion);

		System.out.println("输入数据待加密数据（192.168.1.114:AC-D5-64-56-1C-15,expired:2020-01-01,dataVersion.code:1.0）：");
		String s1 = EncryUtil.encrypt(scan.nextLine());
		System.out.println("加密：" + s1);
		System.out.println("解密：" + EncryUtil.decrypt(s1));
		System.out.println("verify：" + EncryUtil.verify(s1));

		System.out.println("输入数据licence文件路径：");
		String fileName = scan.nextLine();
		fileName = EncryUtil.readCrypt(fileName);
		System.out.println("verify(licence文件)：" + EncryUtil.verify(fileName));
	}

}
